package com.hk.core.authentication.security.authentication.accesstoken;

import com.hk.core.authentication.api.TokenExpiredException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.context.HttpRequestResponseHolder;
import org.springframework.security.web.context.SecurityContextRepository;

import java.util.Objects;


/**
 * 这个可以放在 {@link org.springframework.security.web.context.SecurityContextHolderFilter#securityContextRepository} 中，通过这个过滤器实现认证
 * 而不需要 {@link AccessTokenAuthenticationFilter}
 */
@Slf4j
@RequiredArgsConstructor
public class AccessTokenSecurityContextRepository implements SecurityContextRepository {

    private final AuthenticationConverter authenticationConverter;

    @Override
    public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
        HttpServletRequest request = requestResponseHolder.getRequest();
        try {
            Authentication authentication = authenticationConverter.convert(request);
            return new SecurityContextImpl(authentication);
        } catch (TokenExpiredException e) {
            log.warn("Token expired,:token value:{},expiresAt:{},msg:{}", e.getToken(), e.getExpiresAt(), e.getMessage());
            return new SecurityContextImpl();
        }
    }

    @Override
    public void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response) {

    }

    @Override
    public boolean containsContext(HttpServletRequest request) {
        try {
            Authentication authentication = authenticationConverter.convert(request);
            return Objects.nonNull(authentication);
        } catch (TokenExpiredException e) {
            log.warn("Token expired,:token:{},expiresAt:{},msg:{}", e.getToken(), e.getExpiresAt(), e.getMessage());
            return false;
        }
    }
}
